import java.util.*;
import java.lang.*;

class MoveTimerTask extends TimerTask
{
	int[] moveCoord = new int[2];
	int[] newMove;
	public MoveTimerTask(int[] _newMove)
	{
		newMove = _newMove;
	}
	public void run()
	{
		System.out.println("------------------------------------------------");
		System.out.print("Sending Move\n");
		System.out.println("-------------------------------------------------");
		//put coords in move
		newMove[0] = moveCoord[0];
		newMove[1] = moveCoord[1];
	}
	public void updateMoveCoord(int[] _moveCoord)
	{
		moveCoord = _moveCoord;
	}
}

public class BetterPlayer extends Player 
{
	String color;
	int pieces;
	int player;
	int playerSpace;
	int otherPlayerSpace;
	int boardSize;
	MinMaxTree decisionTree;
	final int[][] initialBoardState;
	int[][] boardValues;
	
    public BetterPlayer(int _boardSize, int p) 
    {
  		super(p);
    	pieces = 0;
    	boardSize = _boardSize;
		player = p;
		if(player == 1) // this should be 0 for keyser's code
		{
			color = "green";
			playerSpace = -1;
			otherPlayerSpace = 1;
		} else
		{
			color = "blue";
			playerSpace = 1;
			otherPlayerSpace = -1;
		}
		initialBoardState = new int[_boardSize][_boardSize];
		int i,j;
		for (i = 0; i < _boardSize; i++)
		{
			for (j = 0; j < _boardSize; j++)
			{
				initialBoardState[i][j] = 0;
			}
		}
		initialBoardState[_boardSize/2-1][_boardSize/2] = 1;
		initialBoardState[_boardSize/2][_boardSize/2-1] = 1;
		initialBoardState[_boardSize/2-1][_boardSize/2-1] = -1;
		initialBoardState[_boardSize/2][_boardSize/2] = -1;
		
		//populate board values
		boardValues = new int[_boardSize][_boardSize];
		//default values
		for (i = 0; i < _boardSize; i++)
		{
			for (j = 0; j < _boardSize; j++)
			{
				boardValues[i][j] = 1;
			}
		}
		//side values
		for (i = 0; i < _boardSize; i++)
		{
			boardValues[0][i] = 2;
			boardValues[i][0] = 2;
			boardValues[_boardSize-1][i] = 2;
			boardValues[i][_boardSize-1] = 2;
		}
		//corners
		boardValues[0][0] = 50;
		boardValues[0][_boardSize-1] = 50;
		boardValues[_boardSize-1][0] = 50;
		boardValues[_boardSize-1][_boardSize-1] = 50;
		//c Squares
		boardValues[0][1] = -1;
		boardValues[1][0] = -1;
		boardValues[0][_boardSize-2] = -1;
		boardValues[1][_boardSize-1] = -1;
		boardValues[_boardSize-2][0] = -1;
		boardValues[_boardSize-1][1] = -1;
		boardValues[_boardSize-1][_boardSize-2] = -1;
		boardValues[_boardSize-2][_boardSize-1] = -1;
		//x squares
		boardValues[1][1] = -10;
		boardValues[1][_boardSize-2] = -10;
		boardValues[_boardSize-2][1] = -10;
		boardValues[_boardSize-2][_boardSize-2] = -10;
		//next to c values
		boardValues[0][2] = 5;
		boardValues[2][0] = 5;
		boardValues[0][boardSize-3] = 5;
		boardValues[2][_boardSize-1] = 5;
		boardValues[_boardSize-3][0] = 5;
		boardValues[_boardSize-1][2] = 5;
		boardValues[_boardSize-1][_boardSize-3] = 5;
		boardValues[_boardSize-3][_boardSize-1] = 5;
		int a, b;
		System.out.print("print state\n");
		for (a = 0; a < boardSize; a++)
		{
			for (b = 0; b < boardSize; b++)
			{
				System.out.print(initialBoardState[b][a]);
				System.out.print(" ");
			}
			System.out.print("\n");
		}
		
		//if you are second player, set up decision tree
		if (color == "blue")
		{
			decisionTree = new MinMaxTree<int[][]>(initialBoardState, 2, 1);
			MinMaxNode rootNode = decisionTree.getRootNode();
			List moves = new ArrayList(3);
			for (i = 0; i < boardSize; i++)
			{
				for (j = 0; j < boardSize; j++)
				{
					if (isValid(initialBoardState, i, j, 1))
					{
						int[] move;
						move = new int[2];
						move[0] = i;
						move[1] = j;
						moves.add(move);
					}
				}
			}
			//add child node for each move
			for (i = 0; i < moves.size(); i++)
			{
				System.out.print("initial state\n");
				for (a = 0; a < boardSize; a++)
				{
					for (b = 0; b < boardSize; b++)
					{
						System.out.print(initialBoardState[b][a]);
						System.out.print(" ");
					}
					System.out.print("\n");
				}
				int[][] tmpstate = copyState(initialBoardState);
				int[][] newState = createState(tmpstate, (int[])moves.get(i), 1);
				List aMove = new ArrayList(2);
				aMove.add(((int[])(moves.get(i)))[0]);
				aMove.add(((int[])(moves.get(i)))[1]);
				MinMaxNode<int[][]> aChild = new MinMaxNode(newState, aMove, 2, 0);
				rootNode.addChild(aChild);
				evalUtility(aChild);
				System.out.print("Utility: ");
				System.out.println(aChild.getUtilValue());
				System.out.print("new state\n");
				for (a = 0; a < boardSize; a++)
				{
					for (b = 0; b < boardSize; b++)
					{
						System.out.print(newState[b][a]);
						System.out.print(" ");
					}
					System.out.print("\n");
				}
			}
		}
    }
    
    /*
     *BoardState -1 = black(green), 1 = white(blue), 0 = empty
     */
    public void makeMove(int boardSize, int[][] boardState, int[] lastMove, Long maxTime, int[] newMove)
    {
    	System.out.println("------------------------------------------------------");
    	System.out.println("Making a move");
    	System.out.println("-------------------------------------------------------");
    	Long timeUp = System.currentTimeMillis() + 12000;
    	
    	Timer moveTimer = new Timer();
    	MoveTimerTask task = new MoveTimerTask(newMove);
		moveTimer.schedule(task, 10000);
		//if last move is a pass, rebuild tree, children has no children (assuming if you a first player, a pass is given)
		if (((lastMove[0] == 0 && lastMove[1] == -1) || (lastMove[0] == -1 && lastMove[1] == 0)) || (!possibleState()))
		{
			decisionTree = new MinMaxTree<int[][]>(boardState, 2, 0);
		} else //else recover tree state
		{
			//get children of root
			List<MinMaxNode<int[][]>> children = decisionTree.getRootNode().getChildren();
			//find which state matches current state
			int i;
			for (i = 0; i < children.size(); i++)
			{
				System.out.print("Checking: ");
				System.out.println(i);
				List<MinMaxNode<int[][]>> nodes = children.get(i).getChildren();
				for (int j = 0; j < nodes.size(); j++)
				{
					if (equalsState(nodes.get(j).getState(), boardState))
					{
						System.out.print("Found the correct state\n");
						printState(nodes.get(j).getState());
						decisionTree.updateRootNode(nodes.get(j));
						break;
					}
				}
			} 
		}
		//populate to at least 1 deep
		MinMaxNode<int[][]> rootNode = decisionTree.getRootNode();
		if (((List)rootNode.getChildren()).size() == 0)
		{
			//make new states
			List moves = new ArrayList(10);
			//find all valid moves -- threading possibility
			for (int i = 0; i < boardSize; i++)
			{
				for (int j = 0; j < boardSize; j++)
				{
					if (isValid(boardState, i, j, 0))
					{
						int[] move;
						move = new int[2];
						move[0] = i;
						move[1] = j;
						moves.add(move);
					}
				}
			}
			//create nodes
			for (int i = 0; i < moves.size(); i++)
			{
				int[][] tmpstate = copyState((int[][])rootNode.getState());
				int[][] newState = createState(tmpstate, (int[])moves.get(i), 0);
				List aMove = new ArrayList(2);
				aMove.add(((int[])(moves.get(i)))[0]);
				aMove.add(((int[])(moves.get(i)))[1]);
				MinMaxNode<int[][]> aChild = new MinMaxNode(newState, aMove, 2, 1);
				rootNode.addChild(aChild);
				System.out.println("Evaluating utility of " + aMove.get(0) + " " + aMove.get(1));
				evalUtility(aChild);
				
			}
		}
		//choose best move sofar
		List<MinMaxNode<int[][]>> children = rootNode.getChildren();
		int bestUtility = children.get(0).getUtilValue();
		task.updateMoveCoord(children.get(0).getMove());
		for (int i = 1; i < children.size(); i++)
		{
			if (children.get(i).getUtilValue() > bestUtility)
			{
				bestUtility = children.get(i).getUtilValue();
				task.updateMoveCoord(children.get(i).getMove());
			}
		}
		//printing all valid moves for testing
		System.out.print("CPU's valid moves:\n");
		List<MinMaxNode<int[][]>> nodes = rootNode.getChildren();
		for (int i = 0; i < nodes.size(); i++)
		{
			System.out.print("Move: ");
			System.out.println(i);
			System.out.print("Utility: ");
			System.out.println(nodes.get(i).getUtilValue());
			printState(nodes.get(i).getState());
		}
		/*
		List<MinMaxNode<int[][]>> leaves = getLeaves(rootNode);
		for (int i = 0; i < leaves.size(); i++)
		{
			int[] aMove = leaves.get(i).getMove();
			System.out.println("Leaf x: " + aMove[0] + " y: " + aMove[1]);
		}
		int bestUtil = minimax(rootNode, 1);
		System.out.println("bestUtil: " + bestUtil);
		
		*/
		System.out.println(timeUp);
		System.out.println(System.currentTimeMillis());
		while (timeUp > System.currentTimeMillis())
		{
			
			System.out.println("---------------------");
			System.out.println("Finding another level");
			System.out.println("---------------------");
			//get leaf nodes
			List<MinMaxNode<int[][]>> leaves = new ArrayList(0);
			leaves = getLeaves(decisionTree.getRootNode());
			System.out.println("Leaves");
			for (int i = 0; i < leaves.size(); i++)
			{
				int[] move = leaves.get(i).getMove();
				System.out.println("x: " + move[0] + " y: " + move[1]);
			}
			int turn = leaves.get(0).getTurn();
			for (int i = 0; i < leaves.size(); i++)
			{
				if (timeUp < System.currentTimeMillis())
					break;
				for (int a = 0; a < boardSize; a++)
				{
					if (timeUp < System.currentTimeMillis())
						break;
					for (int b = 0; b < boardSize; b++)
					{
						if (timeUp < System.currentTimeMillis())
							break;
						if (isValid(leaves.get(i).getState(), a, b, turn))
						{
							int otherTurn;
							if (turn == 0)
							{
								otherTurn = 1;
							} else
							{
								otherTurn = 0;
							}
							int[] move = new int[2];
							move[0] = a;
							move[1] = b;
							int[][] tmpstate = copyState((int[][])leaves.get(i).getState());
							int[][] newState = createState(tmpstate, move, turn); //right?
							List aMove = new ArrayList(2);
							aMove.add(a);
							aMove.add(b);
							MinMaxNode<int[][]> aChild = new MinMaxNode(newState, aMove, 2, otherTurn);
							printState(newState);
							leaves.get(i).addChild(aChild);
							//System.out.println("Evaluating utility of " + aMove.get(0) + " " + aMove.get(1));
							evalUtility(aChild);
						}
					}
				}
			}
			//if (timeUp < System.currentTimeMillis())
			//	break;
			//run minmax
			MinMaxNode<int[][]> theRootNode = decisionTree.getRootNode();
			int bestUtil = minimax(theRootNode, 1);
			List<MinMaxNode<int[][]>> theChildren = theRootNode.getChildren();
			for (int i = 0; i < theChildren.size(); i++)
			{
				if (bestUtil == theChildren.get(i).getUtilValue())
				{
					task.updateMoveCoord(theChildren.get(i).getMove());
					break;
				}
			}
			System.out.println("-----------------------------------------------");
			System.out.println("Done finding another level");
			System.out.println("------------------------------------------------");
		}
		//populate decisionTree
		//choose a best move so far
		//prune tree
		//go for more depth
		//repeat prune -> depth
		//time up
		//while timer is not up, continue
    }
    public void makeBadMove(int boardSize, int[][] boardState, int[] lastMove, Long maxTime, int[] newMove)
    {
    	System.out.println("------------------------------------------------------");
    	System.out.println("Making a move");
    	System.out.println("-------------------------------------------------------");
    	Long timeUp = System.currentTimeMillis() + 12000;
    	
    	Timer moveTimer = new Timer();
    	MoveTimerTask task = new MoveTimerTask(newMove);
		moveTimer.schedule(task, 10000);
		//if last move is a pass, rebuild tree, children has no children (assuming if you a first player, a pass is given)
		if (((lastMove[0] == 0 && lastMove[1] == -1) || (lastMove[0] == -1 && lastMove[1] == 0)) || (!possibleState()))
		{
			decisionTree = new MinMaxTree<int[][]>(boardState, 2, 0);
		} else //else recover tree state
		{
			//get children of root
			List<MinMaxNode<int[][]>> children = decisionTree.getRootNode().getChildren();
			//find which state matches current state
			int i;
			for (i = 0; i < children.size(); i++)
			{
				System.out.print("Checking: ");
				System.out.println(i);
				List<MinMaxNode<int[][]>> nodes = children.get(i).getChildren();
				for (int j = 0; j < nodes.size(); j++)
				{
					if (equalsState(nodes.get(j).getState(), boardState))
					{
						System.out.print("Found the correct state\n");
						printState(nodes.get(j).getState());
						decisionTree.updateRootNode(nodes.get(j));
						break;
					}
				}
			} 
		}
		//populate to at least 1 deep
		MinMaxNode<int[][]> rootNode = decisionTree.getRootNode();
		if (((List)rootNode.getChildren()).size() == 0)
		{
			//make new states
			List moves = new ArrayList(10);
			//find all valid moves -- threading possibility
			for (int i = 0; i < boardSize; i++)
			{
				for (int j = 0; j < boardSize; j++)
				{
					if (isValid(boardState, i, j, 0))
					{
						int[] move;
						move = new int[2];
						move[0] = i;
						move[1] = j;
						moves.add(move);
					}
				}
			}
			//create nodes
			for (int i = 0; i < moves.size(); i++)
			{
				int[][] tmpstate = copyState((int[][])rootNode.getState());
				int[][] newState = createState(tmpstate, (int[])moves.get(i), 0);
				List aMove = new ArrayList(2);
				aMove.add(((int[])(moves.get(i)))[0]);
				aMove.add(((int[])(moves.get(i)))[1]);
				MinMaxNode<int[][]> aChild = new MinMaxNode(newState, aMove, 2, 1);
				rootNode.addChild(aChild);
				System.out.println("Evaluating utility of " + aMove.get(0) + " " + aMove.get(1));
				evalUtility(aChild);
				
			}
		}
		//choose best move sofar
		List<MinMaxNode<int[][]>> children = rootNode.getChildren();
		int bestUtility = children.get(0).getUtilValue();
		task.updateMoveCoord(children.get(0).getMove());
		for (int i = 1; i < children.size(); i++)
		{
			if (children.get(i).getUtilValue() < bestUtility)
			{
				bestUtility = children.get(i).getUtilValue();
				task.updateMoveCoord(children.get(i).getMove());
			}
		}
		//printing all valid moves for testing
		System.out.print("CPU's valid moves:\n");
		List<MinMaxNode<int[][]>> nodes = rootNode.getChildren();
		for (int i = 0; i < nodes.size(); i++)
		{
			System.out.print("Move: ");
			System.out.println(i);
			System.out.print("Utility: ");
			System.out.println(nodes.get(i).getUtilValue());
			printState(nodes.get(i).getState());
		}
		/*
		List<MinMaxNode<int[][]>> leaves = getLeaves(rootNode);
		for (int i = 0; i < leaves.size(); i++)
		{
			int[] aMove = leaves.get(i).getMove();
			System.out.println("Leaf x: " + aMove[0] + " y: " + aMove[1]);
		}
		int bestUtil = minimax(rootNode, 1);
		System.out.println("bestUtil: " + bestUtil);
		
		*/
		System.out.println(timeUp);
		System.out.println(System.currentTimeMillis());
		while (timeUp > System.currentTimeMillis())
		{
			
			System.out.println("---------------------");
			System.out.println("Finding another level");
			System.out.println("---------------------");
			//get leaf nodes
			List<MinMaxNode<int[][]>> leaves = new ArrayList(0);
			leaves = getLeaves(decisionTree.getRootNode());
			System.out.println("Leaves");
			for (int i = 0; i < leaves.size(); i++)
			{
				int[] move = leaves.get(i).getMove();
				System.out.println("x: " + move[0] + " y: " + move[1]);
			}
			int turn = leaves.get(0).getTurn();
			for (int i = 0; i < leaves.size(); i++)
			{
				if (timeUp < System.currentTimeMillis())
					break;
				for (int a = 0; a < boardSize; a++)
				{
					if (timeUp < System.currentTimeMillis())
						break;
					for (int b = 0; b < boardSize; b++)
					{
						if (timeUp < System.currentTimeMillis())
							break;
						if (isValid(leaves.get(i).getState(), a, b, turn))
						{
							int otherTurn;
							if (turn == 0)
							{
								otherTurn = 1;
							} else
							{
								otherTurn = 0;
							}
							int[] move = new int[2];
							move[0] = a;
							move[1] = b;
							int[][] tmpstate = copyState((int[][])leaves.get(i).getState());
							int[][] newState = createState(tmpstate, move, turn); //right?
							List aMove = new ArrayList(2);
							aMove.add(a);
							aMove.add(b);
							MinMaxNode<int[][]> aChild = new MinMaxNode(newState, aMove, 2, otherTurn);
							printState(newState);
							leaves.get(i).addChild(aChild);
							//System.out.println("Evaluating utility of " + aMove.get(0) + " " + aMove.get(1));
							evalUtility(aChild);
						}
					}
				}
			}
			//if (timeUp < System.currentTimeMillis())
			//	break;
			//run minmax
			MinMaxNode<int[][]> theRootNode = decisionTree.getRootNode();
			int bestUtil = minimaxBad(theRootNode, 1);
			List<MinMaxNode<int[][]>> theChildren = theRootNode.getChildren();
			for (int i = 0; i < theChildren.size(); i++)
			{
				if (bestUtil == theChildren.get(i).getUtilValue())
				{
					task.updateMoveCoord(theChildren.get(i).getMove());
					break;
				}
			}
			System.out.println("-----------------------------------------------");
			System.out.println("Done finding another level");
			System.out.println("------------------------------------------------");
		}
		//populate decisionTree
		//choose a best move so far
		//prune tree
		//go for more depth
		//repeat prune -> depth
		//time up
		//while timer is not up, continue
    }
    
    public List<MinMaxNode<int[][]>> getLeaves(MinMaxNode<int[][]> node)
    {
    	List<MinMaxNode<int[][]>> children = node.getChildren();
    	if (children.size() == 0)
    	{
    		List<MinMaxNode<int[][]>> leaves = new ArrayList(0);
    		leaves.add(node);
    		return leaves;
    	} else
    	{
    		List<MinMaxNode<int[][]>> leaves = new ArrayList(1);
    		int csize = children.size();
    		for (int i = 0; i < csize; i++)
    		{
    			leaves.addAll(getLeaves(children.get(i)));
    		}
    		return leaves;
    	}
    }
    public boolean possibleState()
    {
    	List<MinMaxNode<int[][]>> children = decisionTree.getRootNode().getChildren();
    	for (int i = 0; i < children.size(); i++)
    	{
    		if (children.get(i).getChildren().size() > 0)
    			return true; 
    	}
    	return false;
    }
    public int[][] copyState(int[][] _state)
    {
    	int[][] newState = new int[boardSize][boardSize];
    	int c, d;
    	for (c = 0; c < boardSize; c++)
    	{
    		for (d = 0; d < boardSize; d++)
    		{
    			newState[c][d] = _state[c][d];
    		}
    	}
    	return newState;
    }
    public boolean equalsState(int[][] state1, int[][]state2)
    {
    	int i, j;
    	for (i = 0; i < boardSize; i++)
    	{
    		for (j = 0; j < boardSize; j++)
    		{
    			if (state1[i][j] != state2[i][j])
    				return false;
    		}
    	}
    	return true;
    }
    public int minimax(MinMaxNode<int[][]> node, int depth)
    {
    	List<MinMaxNode<int[][]>> children = node.getChildren();
    	int turn = node.getTurn();
    	if (children.size() == 0 || depth == 4)
    	{
    		return node.getUtilValue();	
    	}
    	if (turn == 1)
    	{
    		int beta =  10000; //some very large number
    		for (int i = 0; i < children.size(); i++)
    		{
    			int temp = minimax(children.get(i), depth + 1);
    			if (temp < beta)
    				beta = temp;
    		}
    		node.setUtilValue(beta);
    		return beta;
    	} else
    	{
    		int alpha = -10000; 
    		for (int i = 0; i < children.size(); i++)
    		{
    			int temp = minimax(children.get(i), depth + 1);
    			if (temp > alpha)
    				alpha = temp;
    		}
    		node.setUtilValue(alpha);
    		return alpha;
    	}
    }
    public int minimaxBad(MinMaxNode<int[][]> node, int depth)
    {
    	List<MinMaxNode<int[][]>> children = node.getChildren();
    	int turn = node.getTurn();
    	if (children.size() == 0 || depth == 4)
    	{
    		return node.getUtilValue();	
    	}
    	if (turn == 0)
    	{
    		int beta =  10000; //some very large number
    		for (int i = 0; i < children.size(); i++)
    		{
    			int temp = minimax(children.get(i), depth + 1);
    			if (temp < beta)
    				beta = temp;
    		}
    		node.setUtilValue(beta);
    		return beta;
    	} else
    	{
    		int alpha = -10000; 
    		for (int i = 0; i < children.size(); i++)
    		{
    			int temp = minimax(children.get(i), depth + 1);
    			if (temp > alpha)
    				alpha = temp;
    		}
    		node.setUtilValue(alpha);
    		return alpha;
    	}
    }
    
    public void printState(int[][] state)
    {
    	for (int i = 0; i < boardSize; i++)
    	{
    		for (int j = 0; j < boardSize; j++)
    		{
    			System.out.print(state[j][i]);
    			System.out.print(" ");
    		}
    		System.out.println();
    	}
    }
    
    //valid move functions
    private boolean emptySpace(int[][] boardState, int x, int y)
    {
    	if (boardState[x][y] == 0)
    		return true;
    	return false;
    }
    private boolean nextToOpponentPiece(int[][] boardState, int x, int y, int turn)
    {
    	if (turn == 0) // your turn
    	{
    	if (x != boardSize-1)
    		if (boardState[x+1][y] == otherPlayerSpace)
    			return true;
    	if (x != 0)
    		if (boardState[x-1][y] == otherPlayerSpace)
    			return true;
    	if (y != boardSize-1)
    		if (boardState[x][y+1] == otherPlayerSpace)
    			return true;
    	if (y != 0)
    		if (boardState[x][y-1] == otherPlayerSpace)
    			return true;
    	if ((x != boardSize-1) && (y != boardSize-1))
    		if (boardState[x+1][y+1] == otherPlayerSpace)
    			return true;
    	if ((x != boardSize-1) && (y != 0))
    		if (boardState[x+1][y-1] == otherPlayerSpace)
    			return true;
    	if ((x != 0) && (y != boardSize-1))
    		if (boardState[x-1][y+1] == otherPlayerSpace)
    			return true;
    	if ((x != 0) && (y != 0))
    		if (boardState[x-1][y-1] == otherPlayerSpace)
    			return true;
    	} else //other player's turn
    	{
    	if (x != boardSize-1)
    		if (boardState[x+1][y] == playerSpace)
    			return true;
    	if (x != 0)
    		if (boardState[x-1][y] == playerSpace)
    			return true;
    	if (y != boardSize-1)
    		if (boardState[x][y+1] == playerSpace)
    			return true;
    	if (y != 0)
    		if (boardState[x][y-1] == playerSpace)
    			return true;
    	if ((x != boardSize-1) && (y != boardSize-1))
    		if (boardState[x+1][y+1] == playerSpace)
    			return true;
    	if ((x != boardSize-1) && (y != 0))
    		if (boardState[x+1][y-1] == playerSpace)
    			return true;
    	if ((x != 0) && (y != boardSize-1))
    		if (boardState[x-1][y+1] == playerSpace)
    			return true;
    	if ((x != 0) && (y != 0))
    		if (boardState[x-1][y-1] == playerSpace)
    			return true;
    	}
    	return false;
    } //possibly obsolete
    private boolean checkUp(int[][] boardState, int x, int y, int turn)
    {
    	if (turn == 0) //your turn
    	{
    	int i = x;
    	int j = y-1;
    	if (j >= 0)
    		if (boardState[i][j] == otherPlayerSpace)
    			while (j >= 0)
    			{
    				if (boardState[i][j] == 0)
    					break;
    				if (boardState[i][j] == playerSpace)
    				{
    					return true;
    				}
    				j--;
    			}
    	} else //opponent's turn
    	{
    	int i = x;
    	int j = y-1;
    	if (j >= 0)
    		if (boardState[i][j] == playerSpace)
    			while (j >= 0)
    			{
    				if (boardState[i][j] == 0)
    					break;
    				if (boardState[i][j] == otherPlayerSpace)
    				{
    					return true;
    				}
    				j--;
    			}
    	}
    	return false;
    }
    private boolean checkDown(int[][] boardState, int x, int y, int turn)
    {
    	if (turn == 0) //your turn
    	{
    	int i = x;
    	int j = y+1;
    	if (j < boardSize)
    		if (boardState[i][j] == otherPlayerSpace)
    			while ((j < boardSize))
    			{
    				if (boardState[i][j] == 0)
    					break;
    				if (boardState[i][j] == playerSpace)
    					return true;
    				j++;
    			}
    	} else //opponent's turn
    	{
    	int i = x;
    	int j = y+1;
    	if (j < boardSize)
    		if (boardState[i][j] == playerSpace)
    			while ((j < boardSize))
    			{
    				if (boardState[i][j] == 0)
    					break;
    				if (boardState[i][j] == otherPlayerSpace)
    					return true;
    				j++;
    			}
    	}
    	return false;
    }
    private boolean checkRight(int[][] boardState, int x, int y, int turn)
    {
    	if (turn == 0)
    	{
    	int i = x+1;
    	int j = y;
    	if (i < boardSize)
    		if (boardState[i][j] == otherPlayerSpace)
    			while ((i < boardSize))
    			{
    				if (boardState[i][j] == 0)
    					break;
    				if (boardState[i][j] == playerSpace)
    					return true;
    				i++;
    			}
    	} else //opponent's turn
    	{
    	int i = x+1;
    	int j = y;
    	if (i < boardSize)
    		if (boardState[i][j] == playerSpace)
    			while ((i < boardSize))
    			{
    				if (boardState[i][j] == 0)
    					break;
    				if (boardState[i][j] == otherPlayerSpace)
    					return true;
    				i++;
    			}
    	}
    	return false;
    }
    private boolean checkLeft(int[][] boardState, int x, int y, int turn)
    {
    	if (turn == 0)
    	{
    	int i = x-1;
    	int j = y;
    	if (i >= 0)
    		if (boardState[i][j] == otherPlayerSpace)
    			while (i >= 0)
    			{
    				if (boardState[i][j] == 0)
    					break;
    				if (boardState[i][j] == playerSpace)
    					return true;
    				i--;
    			}
    	} else //opponent's turn
    	{
    	int i = x-1;
    	int j = y;
    	if (i >= 0)
    		if (boardState[i][j] == playerSpace)
    			while (i >= 0)
    			{
    				if (boardState[i][j] == 0)
    					break;
    				if (boardState[i][j] == otherPlayerSpace)
    					return true;
    				i--;
    			}
    	}
    	return false;
    }
    private boolean checkUpRight(int [][] boardState, int x, int y, int turn)
    {
    	if (turn == 0)
    	{
    	int i = x+1;
    	int j = y-1;
    	if ((i < boardSize) && (j >= 0))
    		if (boardState[i][j] == otherPlayerSpace)
    			while ((i < boardSize) && (j >= 0))
    			{
    				if (boardState[i][j] == 0)
    					break;
    				if (boardState[i][j] == playerSpace)
    					return true;
    				i++;
    				j--;
    			}
    	} else
    	{
        int i = x+1;
    	int j = y-1;
    	if ((i < boardSize) && (j >= 0))
    		if (boardState[i][j] == playerSpace)
    			while ((i < boardSize) && (j >= 0))
    			{
    				if (boardState[i][j] == 0)
    					break;
    				if (boardState[i][j] == otherPlayerSpace)
    					return true;
    				i++;
    				j--;
    			}
    	}
    	return false;
    }
    private boolean checkUpLeft(int[][] boardState, int x, int y, int turn)
    {
    	if (turn == 0)
    	{
    	int i = x-1;
    	int j = y-1;
    	if ((i >= 0) && (j >= 0))
    		if (boardState[i][j] == otherPlayerSpace)
    			while ((i >= 0) && (j >= 0))
    			{
    				if (boardState[i][j] == 0)
    					break;
    				if (boardState[i][j] == playerSpace)
    					return true;
    				i--;
    				j--;
    			}
    	} else
    	{
    	int i = x-1;
    	int j = y-1;
    	if ((i >= 0) && (j >= 0))
    		if (boardState[i][j] == playerSpace)
    			while ((i >= 0) && (j >= 0))
    			{
    				if (boardState[i][j] == 0)
    					break;
    				if (boardState[i][j] == otherPlayerSpace)
    					return true;
    				i--;
    				j--;
    			}
    	}
    	return false;
    }
    private boolean checkDownRight(int[][] boardState, int x, int y, int turn)
    {
    	if (turn == 0)
    	{
    	int i = x+1;
    	int j = y+1;
    	if ((i < boardSize) && (j < boardSize))
    		if (boardState[i][j] == otherPlayerSpace)
    			while ((i < boardSize) && (j < boardSize))
    			{
    				if (boardState[i][j] == 0)
    					break;
    				if (boardState[i][j] == playerSpace)
    					return true;
    				i++;
    				j++;
    			}
    	} else
    	{
    	int i = x+1;
    	int j = y+1;
    	if ((i < boardSize) && (j < boardSize))
    		if (boardState[i][j] == playerSpace)
    			while ((i < boardSize) && (j < boardSize))
    			{
    				if (boardState[i][j] == 0)
    					break;
    				if (boardState[i][j] == otherPlayerSpace)
    					return true;
    				i++;
    				j++;
    			}
    	}
    	return false;
    }
    private boolean checkDownLeft(int[][] boardState, int x, int y, int turn)
    {
    	if (turn == 0)
    	{
    	int i = x-1;
    	int j = y+1;
    	if ((i >= 0) && j < boardSize)
    		if (boardState[i][j] == otherPlayerSpace)
    			while ((i >= 0) && (j < boardSize))
    			{
    				if (boardState[i][j] == 0)
    					break;
    				if (boardState[i][j] == playerSpace)
    					return true;
    				i--;
    				j++;
    			}
    	} else
    	{
     	int i = x-1;
    	int j = y+1;
    	if ((i >= 0) && j < boardSize)
    		if (boardState[i][j] == playerSpace)
    			while ((i >= 0) && (j < boardSize))
    			{
    				if (boardState[i][j] == 0)
    					break;
    				if (boardState[i][j] == otherPlayerSpace)
    					return true;
    				i--;
    				j++;
    			}
    	}
    	return false;
    }
    private boolean captureable(int[][] boardState, int x, int y, int turn)
    {
    	//count up
    	if (checkUp(boardState, x, y, turn))
    		return true;
    	/*
    	int i = x;
    	int j = y-1;
    	if (j >= 0)
    		if (boardState[i][j] == otherPlayerSpace)
    			while (j >= 0)
    			{
    				if (boardState[i][j] == 0)
    					break;
    				if (boardState[i][j] == playerSpace)
    				{
    					return true;
    				}
    				j--;
    			}
    	*/
    	
    	//count down
    	if (checkDown(boardState, x, y, turn))
    		return true;
    	/*
    	i = x;
    	j = y+1;
    	if (j < boardSize)
    		if (boardState[i][j] == otherPlayerSpace)
    			while ((j < boardSize))
    			{
    				if (boardState[i][j] == 0)
    					break;
    				if (boardState[i][j] == playerSpace)
    					return true;
    				j++;
    			}
    	*/
    	//count right
    	if (checkRight(boardState, x, y, turn))
    		return true;
    	/*
    	i = x+1;
    	j = y;
    	if (i < boardSize)
    		if (boardState[i][j] == otherPlayerSpace)
    			while ((i < boardSize))
    			{
    				if (boardState[i][j] == 0)
    					break;
    				if (boardState[i][j] == playerSpace)
    					return true;
    				i++;
    			}
    	*/
    	//count left
    	if (checkLeft(boardState, x, y, turn))
    		return true;
    	/*
    	i = x-1;
    	j = y;
    	if (i >= 0)
    		if (boardState[i][j] == otherPlayerSpace)
    			while (i >= 0)
    			{
    				if (boardState[i][j] == 0)
    					break;
    				if (boardState[i][j] == playerSpace)
    					return true;
    				i--;
    			}
    	*/
    	//count up-right
    	if (checkUpRight(boardState, x, y, turn))
    		return true;
    	/*
    	i = x+1;
    	j = y-1;
    	if ((i < boardSize) && (j >= 0))
    		if (boardState[i][j] == otherPlayerSpace)
    			while ((i < boardSize) && (j >= 0))
    			{
    				if (boardState[i][j] == 0)
    					break;
    				if (boardState[i][j] == playerSpace)
    					return true;
    				i++;
    				j--;
    			}
    	*/
    	//count up-left
    	if (checkUpLeft(boardState, x, y, turn))
    		return true;
    	/*
    	i = x-1;
    	j = y-1;
    	if ((i >= 0) && (j >= 0))
    		if (boardState[i][j] == otherPlayerSpace)
    			while ((i >= 0) && (j >= 0))
    			{
    				if (boardState[i][j] == 0)
    					break;
    				if (boardState[i][j] == playerSpace)
    					return true;
    				i--;
    				j--;
    			}
    	*/
    	//count down-right
    	if (checkDownRight(boardState, x, y, turn))
    		return true;
    	/*
    	i = x+1;
    	j = y+1;
    	if ((i < boardSize) && (j < boardSize))
    		if (boardState[i][j] == otherPlayerSpace)
    			while ((i < boardSize) && (j < boardSize))
    			{
    				if (boardState[i][j] == 0)
    					break;
    				if (boardState[i][j] == playerSpace)
    					return true;
    				i++;
    				j++;
    			}
    	*/
    	//count down-left
    	if (checkDownLeft(boardState, x, y, turn))
    		return true;
    	/*
    	i = x-1;
    	j = y+1;
    	if ((i >= 0) && j < boardSize)
    		if (boardState[i][j] == otherPlayerSpace)
    			while ((i >= 0) && (j < boardSize))
    			{
    				if (boardState[i][j] == 0)
    					break;
    				if (boardState[i][j] == playerSpace)
    					return true;
    				i--;
    				j++;
    			}
    	*/
    	return false;
    }    
    private boolean isValid(int[][] boardState, int x, int y, int turn)
    {
    	if (emptySpace(boardState, x, y))
    	{
    		//System.out.println("found an empty space");
    		if (nextToOpponentPiece(boardState, x, y, turn))
    		{
    			//System.out.println("found a space next to opponent");
    			if (captureable(boardState, x, y, turn))
    			{
    				System.out.println("found a capturable space");
    				System.out.print("x: ");
    				System.out.println(x);
    				System.out.print("y: ");
    				System.out.println(y);
    				return true;
    			}
    		}
    	}
    	return false;
    }
    //game Management functions to generate states
    private void flipUp(int[][] boardState, int x, int y, int turn)
    {
    	if (turn == 0)
    	{
    	int i = x;
    	int j = y;
    	boardState[i][j] = playerSpace;
    	j--;
    	while (j >= 0 && boardState[i][j] != 0 && boardState[i][j] != playerSpace)
    	{
    		boardState[i][j] = playerSpace;
    		j--;
    	}
    	} else
    	{
    	int i = x;
    	int j = y;
    	boardState[i][j] = otherPlayerSpace;
    	j--;
    	while (j >= 0 && boardState[i][j] != 0 && boardState[i][j] != otherPlayerSpace)
    	{
    		boardState[i][j] = otherPlayerSpace;
    		j--;
    	}
    	}
    }
    private void flipDown(int[][] boardState, int x, int y, int turn)
    {
    	if (turn == 0)
    	{
    	int i = x;
    	int j = y;
    	boardState[i][j] = playerSpace;
    	j++;
    	while (j < boardSize && boardState[i][j] != 0 && boardState[i][j] != playerSpace)
    	{
    		boardState[i][j] = playerSpace;
    		j++;
    	}
    	} else
    	{
    	int i = x;
    	int j = y;
    	boardState[i][j] = otherPlayerSpace;
    	j++;
    	while (j < boardSize && boardState[i][j] != 0 && boardState[i][j] != otherPlayerSpace)
    	{
    		boardState[i][j] = otherPlayerSpace;
    		j++;
    	}
    	}
    }
    private void flipLeft(int[][] boardState, int x, int y, int turn)
    {
    	if (turn == 0)
    	{
    	int i = x;
    	int j = y;
    	boardState[i][j] = playerSpace;
    	i--;
    	while (i >= 0 && boardState[i][j] != 0 && boardState[i][j] != playerSpace)
    	{
    		boardState[i][j] = playerSpace;
    		i--;
    	}
    	} else
    	{
    	int i = x;
    	int j = y;
    	boardState[i][j] = otherPlayerSpace;
    	i--;
    	while (i >= 0 && boardState[i][j] != 0 && boardState[i][j] != otherPlayerSpace)
    	{
    		boardState[i][j] = otherPlayerSpace;
    		i--;
    	}
    	}
    }
    private void flipRight(int[][] boardState, int x, int y, int turn)
    {
    	if (turn == 0)
    	{
    	int i = x;
    	int j = y;
    	boardState[i][j] = playerSpace;
    	i++;
    	while (i < boardSize && boardState[i][j] != 0 && boardState[i][j] != playerSpace)
    	{
    		boardState[i][j] = playerSpace;
    		i++;
    	}
    	} else 
    	{
    	int i = x;
    	int j = y;
    	boardState[i][j] = otherPlayerSpace;
    	i++;
    	while (i < boardSize && boardState[i][j] != 0 && boardState[i][j] != otherPlayerSpace)
    	{
    		boardState[i][j] = otherPlayerSpace;
    		i++;
    	}
    	}
    }
    private void flipUpRight(int[][] boardState, int x, int y, int turn)
    {
    	if (turn == 0)
    	{
    	int i = x;
    	int j = y;
    	boardState[i][j] = playerSpace;
    	i++;
    	j--;
    	while (i < boardSize && j >= 0 && boardState[i][j] != 0 && boardState[i][j] != playerSpace)
    	{
    		boardState[i][j] = playerSpace;
    		i++;
    		j--;
    	}
    	} else
    	{
    	int i = x;
    	int j = y;
    	boardState[i][j] = otherPlayerSpace;
    	i++;
    	j--;
    	while (i < boardSize && j >= 0 && boardState[i][j] != 0 && boardState[i][j] != otherPlayerSpace)
    	{
    		boardState[i][j] = otherPlayerSpace;
    		i++;
    		j--;
    	}
    	}
    }
    private void flipUpLeft(int[][] boardState, int x, int y, int turn)
    {
    	if (turn == 0)
    	{
    	int i = x;
    	int j = y;
    	boardState[i][j] = playerSpace;
    	i--;
    	j--;
    	while (i >= 0 && j >= 0 && boardState[i][j] == otherPlayerSpace)
    	{
    		boardState[i][j] = playerSpace;
    		i--;
    		j--;
    	}
    	} else
    	{
    	int i = x;
    	int j = y;
    	boardState[i][j] = otherPlayerSpace;
    	i--;
    	j--;
    	while (i >= 0 && j >= 0 && boardState[i][j] == playerSpace)
    	{
    		boardState[i][j] = otherPlayerSpace;
    		i--;
    		j--;
    	}
    	}
    }
    private void flipDownRight(int[][] boardState, int x, int y, int turn)
    {
    	if (turn == 0)
    	{
    	int i = x;
    	int j = y;
    	boardState[i][j] = playerSpace;
    	i++;
    	j++;
    	while (i < boardSize && j < boardSize && boardState[i][j] == otherPlayerSpace)
    	{
    		boardState[i][j] = playerSpace;
    		i++;
    		j++;
    	}
    	} else 
    	{
    	int i = x;
    	int j = y;
    	boardState[i][j] = otherPlayerSpace;
    	i++;
    	j++;
    	while (i < boardSize && j < boardSize && boardState[i][j] == playerSpace)
    	{
    		boardState[i][j] = otherPlayerSpace;
    		i++;
    		j++;
    	}
    	}
    }
    private void flipDownLeft(int[][] boardState, int x, int y, int turn)
    {
    	if (turn == 0)
    	{
    	int i = x;
    	int j = y;
    	boardState[i][j] = playerSpace;
    	i--;
    	j++;
    	while (i >= 0 && j < boardSize && boardState[i][j] == otherPlayerSpace)
    	{
    		boardState[i][j] = playerSpace;
    		i--;
    		j++;
    	}
    	} else
    	{
    	int i = x;
    	int j = y;
    	boardState[i][j] = otherPlayerSpace;
    	i--;
    	j++;
    	while (i >= 0 && j < boardSize && boardState[i][j] == playerSpace)
    	{
    		boardState[i][j] = otherPlayerSpace;
    		i--;
    		j++;
    	}
    	}
   }
    private int[][] createState(int[][]boardState, int[] move, int turn) 
    {
    	int[][]newState	= boardState.clone();
    	int x = move[0];
    	int y = move[1];
    	if (checkUp(boardState, x, y, turn))
    		flipUp(newState, x, y, turn);
    	if (checkDown(boardState, x, y, turn))
    		flipDown(newState, x, y, turn);
    	if (checkLeft(boardState, x, y, turn))
    		flipLeft(newState, x, y, turn);
    	if (checkRight(boardState, x, y, turn))
    		flipRight(newState, x, y, turn);
     	if (checkUpLeft(boardState, x, y, turn))
     		flipUpLeft(newState, x, y, turn);
     	if (checkUpRight(boardState, x, y, turn))
     		flipUpRight(newState, x, y, turn);
     	if (checkDownLeft(boardState, x, y, turn))
     		flipDownLeft(newState, x, y, turn);
     	if (checkDownRight(boardState, x, y, turn))
     		flipDownRight(newState, x, y, turn);
     	return newState;
    }
    //Utility functions
    public int evalSpaceValue(int[][] state, int turn)
    {
    	int playerValue = 0;
    	int opponentValue = 0;
    	int i, j;
    	if (turn == 0) //changed to 1?
    	{
    		for (i = 0; i < boardSize; i++)
    		{
    			for (j = 0; j < boardSize; j++)
    			{
    				if (state[i][j] == playerSpace)
    					playerValue += boardValues[i][j];
    				if (state[i][j] == otherPlayerSpace)
    					opponentValue += boardValues[i][j];
    			}
    		}
    	} else
    	{
    		for (i = 0; i < boardSize; i++)
    		{
    			for (j = 0; j < boardSize; j++)
    			{
    				if (state[i][j] == otherPlayerSpace)
    					playerValue += boardValues[i][j];
    				if (state[i][j] == playerSpace)
    					opponentValue += boardValues[i][j];
    			}
    		}
    	}
    	return (playerValue - opponentValue);
    }
    public boolean isCorner(int x, int y)
    {
    	if (x == 0 && y == 0)
    		return true;
    	if (x == 0 && y == boardSize-1)
    		return true;
    	if (x == boardSize-1 && y == 0)
    		return true;
    	if (x == boardSize-1 && y == boardSize-1)
    		return true;
    	return false;
    }
    public boolean cornerBool(int[] move)
    {
    	int x = move[0];
    	int y = move[1];
    	if (x == 0 && y == 0)
    		return true;
    	if (x == 0 && y == boardSize-1)
    		return true;
    	if (x == boardSize-1 && y == 0)
    		return true;
    	if (x == boardSize-1 && y == boardSize-1)
    		return true;
    	return false;
    }
    public boolean cORxBool(int[] move)
    {
    	int x = move[0];
    	int y = move[1];
    	//top left corner
    	if (x == 1 && y == 0)
    		return true;
    	if (x == 0 && y == 1)
    		return true;
    	if (x == 1 && y == 1)
    		return true;
    	//top right corner
    	if (x == boardSize-2 && y == 0)
    		return true;
    	if (x == boardSize-1 && y == 1)
    		return true;
    	if ((x == boardSize-2) && (y == 1))
    		return true;
    	//bottom left corner
    	if (x == 0 && y == boardSize-2)
    		return true;
    	if (x == 1 && y == boardSize-1)
    		return true;
    	if (x == 1 && y == boardSize-2)
    		return true;
    	//bottom right corner
    	if (x == boardSize-1 && y == boardSize-2)
    		return true;
    	if (x == boardSize-2 && y == boardSize-1)
    		return true;
    	if (x == boardSize-2 && y == boardSize-2)
    		return true;
    	return false;
    }
    public int frontierDiscCount(int[][] state, int turn, int[] aMove)
    {
    	int discCount = 0;
    	if (turn == 0)
    	{
    		if (!cornerBool(aMove))
    		{
    			for (int i = 0; i < boardSize; i++)
    			{	
    				for (int j = 0; j < boardSize; j++)
    				{
    					if (state[i][j] == playerSpace)
    					{
    						if ((i == 0 || j == 0 || i == boardSize-1 || j == boardSize-1) && !isCorner(i,j)) //an edge condition
    						{
    							if (j==0) //top edge condition //changed to j
    							{
    								if (state[i][j+1] == 0) //down
    								{
    									discCount++;
    								} else if (state[i-1][j] == 0) //left
    								{
    									discCount++;
    								} else if (state[i+1][j] == 0) //right
    								{
    									discCount++;
    								} else if (state[i+1][j+1] == 0) //down-right
    								{
    									discCount++;
    								} else if (state[i-1][j+1] == 0) //down-left
    								{
    									discCount++;
    								}
    							} else if (i == 0) //left edge condition
    							{
    								if (state[i][j-1] == 0) //up
    								{
    									discCount++;
    								} else if (state[i][j+1] == 0) //down
    								{
    									discCount++;
    								} else if (state[i+1][j] == 0) //right
    								{
    									discCount++;
    								} else if (state[i+1][j-1] == 0) //up-right
    								{
    									discCount++;
    								} else if (state[i+1][j+1] == 0) //down-right
    								{
    									discCount++;
    								}
    							} else if (j == boardSize-1) // bottom edge condition
    							{
    								if (state[i][j-1] == 0) //up
    								{
    									discCount++;
    								} else if (state[i-1][j] == 0) //left
    								{
    									discCount++;
    								} else if (state[i+1][j] == 0) //right
    								{
    									discCount++;
    								} else if (state[i-1][j-1] == 0) //up-left
    								{
    									discCount++;
    								} else if (state[i+1][j-1] == 0) //up-right
    								{
    									discCount++;
    								}
    							} else if (i == boardSize-1) // right edge condition
    							{
    								if (state[i][j-1] == 0) //up
    								{
    									discCount++;
    								} else if (state[i][j+1] == 0) //down
    								{
    									discCount++;
    								} else if (state[i-1][j] == 0) //left
    								{
    									discCount++;
    								} else if (state[i-1][j-1] == 0) //up-left
    								{
    									discCount++;
    								} else if (state[i-1][j+1] == 0) //down-left
    								{
    									discCount++;
    								}
    							}
    						}else if (!isCorner(i,j))  //not on the edge
    						{
    							if (state[i][j-1] == 0) //up
    							{
    								discCount++;
    							} else if (state[i][j+1] == 0) //down
    							{
    								discCount++;
    							} else if (state[i-1][j] == 0) //left
    							{
    								discCount++;
    							} else if (state[i+1][j] == 0) //right
    							{
    								discCount++;
    							} else if (state[i-1][j-1] == 0) //up-left
    							{
    								discCount++;
    							} else if (state[i+1][j-1] == 0) //up-right
    							{
    								discCount++;
    							} else if (state[i+1][j+1] == 0) //down-right
    							{
    								discCount++;
    							} else if (state[i-1][j+1] == 0) //down-left
    							{
    								discCount++;
    							}
    						}
    					}
    				}
    			}
    		}
    	} else
    	{
    		if (!cornerBool(aMove))
    		{
    			for (int i = 0; i < boardSize; i++)
    			{	
    				for (int j = 0; j < boardSize; j++)
    				{
    					if (state[i][j] == playerSpace)
    					{
    						if ((i == 0 || j == 0 || i == boardSize-1 || j == boardSize-1) && !isCorner(i,j)) //an edge condition
    						{
    							if (j==0) //top edge condition //changed to j
    							{
    								if (state[i][j+1] == 0) //down
    								{
    									discCount++;
    								} else if (state[i-1][j] == 0) //left
    								{
    									discCount++;
    								} else if (state[i+1][j] == 0) //right
    								{
    									discCount++;
    								} else if (state[i+1][j+1] == 0) //down-right
    								{
    									discCount++;
    								} else if (state[i-1][j+1] == 0) //down-left
    								{
    									discCount++;
    								}
    							} else if (i == 0) //left edge condition //changed to i?
    							{
    								if (state[i][j-1] == 0) //up
    								{
    									discCount++;
    								} else if (state[i][j+1] == 0) //down
    								{
    									discCount++;
    								} else if (state[i+1][j] == 0) //right
    								{
    									discCount++;
    								} else if (state[i+1][j-1] == 0) //up-right
    								{
    									discCount++;
    								} else if (state[i+1][j+1] == 0) //down-right
    								{
    									discCount++;
    								}
    							} else if (j == boardSize-1) // bottom edge condition //changed to j
    							{
    								if (state[i][j-1] == 0) //up
    								{
    									discCount++;
    								} else if (state[i-1][j] == 0) //left
    								{
    									discCount++;
    								} else if (state[i+1][j] == 0) //right
    								{
    									discCount++;
    								} else if (state[i-1][j-1] == 0) //up-left
    								{
    									discCount++;
    								} else if (state[i+1][j-1] == 0) //up-right
    								{
    									discCount++;
    								}
    							} else if (i == boardSize-1) // right edge condition //changed to i
    							{
    								if (state[i][j-1] == 0) //up
    								{
    									discCount++;
    								} else if (state[i][j+1] == 0) //down
    								{
    									discCount++;
    								} else if (state[i-1][j] == 0) //left
    								{
    									discCount++;
    								} else if (state[i-1][j-1] == 0) //up-left
    								{
    									discCount++;
    								} else if (state[i-1][j+1] == 0) //down-left
    								{
    									discCount++;
    								}
    							}
    						} else if (isCorner(i, j))
    						{
    							discCount++;
    						}else if (!isCorner(i,j)) //not on the edge
    						{
    							if (state[i][j-1] == 0) //up
    							{
    								discCount++;
    							} else if (state[i][j+1] == 0) //down
    							{
    								discCount++;
    							} else if (state[i-1][j] == 0) //left
    							{
    								discCount++;
    							} else if (state[i+1][j] == 0) //right
    							{
    								discCount++;
    							} else if (state[i-1][j-1] == 0) //up-left
    							{
    								discCount++;
    							} else if (state[i+1][j-1] == 0) //up-right
    							{
    								discCount++;
    							} else if (state[i+1][j+1] == 0) //down-right
    							{
    								discCount++;
    							} else if (state[i-1][j+1] == 0) //down-left
    							{
    								discCount++;
    							}
    						}
    					}
    				}
    			}
    		}
    	}
    	return discCount;
    }
    public int interiorDiscCount(int[][] state, int turn)
    {
    	int discCount = 0;
    	int playerPiece;
    	int opponentPiece;
    	if (turn == 0)
    	{
    		playerPiece = playerSpace;
    		opponentPiece = otherPlayerSpace;
    	} else
    	{
    		playerPiece = otherPlayerSpace;
    		opponentPiece = playerSpace;
    	}
    	for (int i = 1; i < boardSize-1; i++)
    	{
    		for (int j = 1; j < boardSize-1; j++)
    		{
    			if (state[i][j] == playerPiece)
    			{
    				if ((state[i][j-1] != 0) && (state[i][j+1] != 0)) //up and down
    					if ((state[i-1][j] != 0) && (state[i+1][j] != 0)) //left and right
    						if ((state[i-1][j-1] != 0) && (state[i+1][j-1] != 0)) //up diagonals
    							if ((state[i+1][j+1] != 0) && (state[i-1][j+1] != 0)) //down-right
    								discCount++;
    			}
    		}
    	}
    	return discCount;
    }
    public int stableDiscCount(int[][] state, int turn) //if disc surrounded by all stable discs it is stable?
    {
    	int discCount = 0;
    	int playerPiece;
    	int opponentPiece;
    	if (turn == 0)
    	{
    		playerPiece = playerSpace;
    		opponentPiece = otherPlayerSpace;
    	} else
    	{
    		playerPiece = otherPlayerSpace;
    		opponentPiece = playerSpace;
    	}
    	boolean side1 = false;
    	boolean side2 = false;
    	if (state[0][0] == playerPiece) //top-left corner
    	{
    		discCount++;
    		int i = 0; //side 1 parameters
    		int j = 0;
    		int k = 0; //side 2 parameters
    		int l = 0; 
    		side1 = true;
    		side2 = true;
    		do {
    			//check sides
    			i++;
    			System.out.println("i: " + i);
    			l++;
    			if (side1)
    				if (state[i][j] == playerPiece)
    				{
    					side1 = true;
    					discCount++;
    				} else
    					side1 = false;
    			if (side2)
    				if (state[k][l] == playerPiece)
    				{
    					side2 = true;
    					discCount++;
    				} else
    					side2 = false;
    			if (side1 && side2)
    			{
    				//check diagonal
    				int m = i-1;
    				int n = j+1;
    				while((m != k) && (n != l) && (state[m][k] != opponentPiece) && (state[m][k] != 0)) 
    				{
    					discCount++;
    					m--;
    					n++;
    				}
    			}
    		}while(((side1) || (side2)) && (i <= (boardSize - 2)) && (l <= (boardSize - 2)));
    	}
    	if (state[boardSize-1][0] == playerSpace) // top-right corner
    	{
    		discCount++;
    		int i = boardSize-1; //side 1 parameters
    		int j = 0;
    		int k = boardSize-1; //side 2 parameters
    		int l = 0; 
    		side1 = true;
    		side2 = true;
    		do {
    			//check sides
    			i--;
    			l++;
    			if (side1)
    				if (state[i][j] == playerPiece)
    					side1 = true;
    				else
    					side1 = false;
    			if (side2)
    				if (state[k][l] == playerPiece)
    					side2 = true;
    				else
    					side2 = false;
    			if (side1 && side2)
    			{
    				//check diagonal
    				int m = i+1;
    				int n = j+1;
    				while((m != k) && (n != l) && (state[m][k] != opponentPiece) && (state[m][k] != 0)) 
    				{
    					discCount++;
    					m++;
    					n++;
    				}
    			}
    		} while((side1 || side2) && (i > 0) && (l < (boardSize-1)));  			
    	}
    	if (state[boardSize-1][boardSize-1] == playerPiece) //bottom-right corner
    	{
    		discCount++;
    		int i = boardSize-1; //side 1 parameters
    		int j = boardSize-1;
    		int k = boardSize-1; //side 2 parameters
    		int l = boardSize-1; 
    		side1 = true;
    		side2 = true;
    		do {
    			//check sides
    			j--;
    			k--;
    			if (side1)
    				if (state[i][j] == playerPiece) // out of bounds error here
    					side1 = true;
    				else
    					side1 = false;
    			if (side2)
    				if (state[k][l] == playerPiece)
    					side2 = true;
    				else
    					side2 = false;
    			if (side1 && side2)
    			{
    				//check diagonal
    				int m = i-1;
    				int n = j+1;
    				while((m != k) && (n != l) && (state[m][k] != opponentPiece) && (state[m][k] != 0)) 
    				{
    					discCount++;
    					m--;
    					n++;
    				}
    			}
    		} while((side1 || side2) && (j > 0) && (k > 0));
    	}
    	if (state[0][boardSize-1] == playerPiece) //bottom-left space
    	{
    		discCount++;
    		int i = 0; //side 1 parameters
    		int j = boardSize-1;
    		int k = 0; //side 2 parameters
    		int l = boardSize-1; 
    		side1 = true;
    		side2 = true;
    		do {
    			//check sides
    			j--;
    			k++;
    			if (side1)
    				if (state[i][j] == playerPiece)
    					side1 = true;
    				else
    					side1 = false;
    			if (side2)
    				if (state[k][l] == playerPiece)
    					side2 = true;
    				else
    					side2 = false;
    			if (side1 && side2)
    			{
    				//check diagonal
    				int m = i+1;
    				int n = j+1;
    				while((m != k) && (n != l) && (state[m][k] != opponentPiece) && (state[m][k] != 0)) 
    				{
    					discCount++;
    					m++;
    					n++;
    				}
    			}
    		} while((side1 || side2) && (j > 0) && (k < boardSize-1));
    	}
    	return discCount;
    }
    public void evalUtility(MinMaxNode<int[][]> node)
    {
    	int utility;
    	int[][] state = new int[boardSize][boardSize];
    	state = node.getState();
    	int turn = node.getTurn();
    	int otherTurn;
    	if (turn == 0)
    		otherTurn = 1;
    	else
    		otherTurn = 0;
    	int[] move = new int[2];
    	move = node.getMove();
    	System.out.println("Evaluating Move: " + move[0] + " " + move[1]);
    	int playerPieceValue = evalSpaceValue(state, turn);
    	System.out.println("Piece Value: " + playerPieceValue);
    	//int opponentPieceValue = evalSpaceValue(state, otherTurn);
    	boolean cORx = cORxBool(move);
    	System.out.println("cORx: " + cORx);     	 
    	boolean corner = cornerBool(move);
    	System.out.println("corner: " + corner);
    	int frontierCount = frontierDiscCount(state, turn, move);
    	System.out.println("Frontier Count: " + frontierCount);
    	int stableDiscs = stableDiscCount(state, turn);
    	System.out.println("Stable Count: " + stableDiscs);
    	int interiorDiscs = interiorDiscCount(state, turn);
    	System.out.println("Interior Count: " + interiorDiscs);
    	utility = playerPieceValue - (2 * frontierCount) + (2 * interiorDiscs) + (3 * stableDiscs);
    	if (cORx)
    		utility -= 25; //flipped signs on these two
    	if (corner)
    		utility += 100;
    	utility -= (2 * node.getChildrenSize());
    	node.setUtilValue(utility);
    }
}
